from typing import List, Dict
from .models import FileInfo
import os

class DataAnalyzer:
    """数据分析器"""
    
    def __init__(self):
        pass
    
    def analyze_directory_sizes(self, file_list: List[FileInfo]) -> Dict[str, Dict]:
        """分析目录大小 - 优化版
        
        Args:
            file_list: 文件信息列表
        
        Returns:
            目录大小统计字典
        """
        # 第一步：创建目录集合和初始化统计信息
        dir_stats = {}
        for file_info in file_list:
            if file_info.is_directory:
                dir_stats[file_info.path] = {
                    'file_count': 0,
                    'total_size': 0,
                    'depth': file_info.depth,
                    'name': file_info.name
                }
        
        # 计算每个目录的文件数量和总大小
        for file_info in file_list:
            if not file_info.is_directory:
                # 更新当前文件所在目录的统计
                parent_path = file_info.parent_path
                if parent_path in dir_stats:
                    dir_stats[parent_path]['file_count'] += 1
                    dir_stats[parent_path]['total_size'] += file_info.size
                
                # 更新所有父级目录的大小
                current_path = parent_path
                while True:
                    parent_dir = os.path.dirname(current_path)
                    if parent_dir == '' or parent_dir not in dir_stats:
                        break
                    dir_stats[parent_dir]['total_size'] += file_info.size
                    current_path = parent_dir
        
        return dir_stats
    
    def find_largest_files(self, file_list: List[FileInfo], top_n: int = 100) -> List[FileInfo]:
        """查找最大的文件 - 优化版
        
        Args:
            file_list: 文件信息列表
            top_n: 返回前N个文件
        
        Returns:
            按大小排序的文件列表
        """
        # 快速过滤并排序
        return sorted(
            [f for f in file_list if not f.is_directory and f.size > 0],  # 排除空文件
            key=lambda x: x.size, 
            reverse=True
        )[:top_n]
    
    def find_empty_directories(self, file_list: List[FileInfo]) -> List[FileInfo]:
        """查找空目录 - 优化版
        
        Args:
            file_list: 文件信息列表
        
        Returns:
            空目录列表
        """
        # 创建路径集合（使用set提高查找效率）
        all_paths = {f.path for f in file_list}
        dir_paths = {d.path: d for d in file_list if d.is_directory}
        
        # 标记有子内容的目录
        non_empty_dirs = set()
        
        # 对于每个路径，标记其所有父目录为非空
        for path in all_paths:
            # 跳过根路径
            if path.count(os.path.sep) <= 1:
                continue
                
            # 遍历所有父目录
            current_path = path
            while True:
                parent_path = os.path.dirname(current_path)
                # 到达根目录时停止
                if parent_path.count(os.path.sep) < 1 or parent_path not in dir_paths:
                    break
                    
                # 标记父目录为非空
                non_empty_dirs.add(parent_path)
                current_path = parent_path
        
        # 找出所有未被标记为非空的目录
        empty_dirs = [dir_paths[d] for d in dir_paths if d not in non_empty_dirs]
        
        return empty_dirs
    
    def get_extension_distribution(self, file_list: List[FileInfo]) -> Dict[str, int]:
        """获取扩展名分布 - 优化版
        
        Args:
            file_list: 文件信息列表
        
        Returns:
            扩展名计数字典
        """
        extension_count = {}
        
        # 直接使用file_info已有的extension属性
        for file_info in file_list:
            if not file_info.is_directory:
                ext = file_info.extension or '(无扩展名)'
                extension_count[ext] = extension_count.get(ext, 0) + 1
        
        return extension_count
    
    def find_duplicate_names(self, file_list: List[FileInfo]) -> Dict[str, List[FileInfo]]:
        """查找同名文件 - 优化版
        
        Args:
            file_list: 文件信息列表
        
        Returns:
            文件名到文件列表的映射
        """
        # 创建文件名到文件对象的映射
        name_map = {}
        
        for file_info in file_list:
            if not file_info.is_directory:
                # 使用setdefault优化字典操作
                files = name_map.setdefault(file_info.name, [])
                files.append(file_info)
        
        # 过滤出有重复的文件名，并限制返回数量以提高性能
        duplicates = {}
        count = 0
        # 按重复次数排序并限制返回数量
        for name, files in sorted(name_map.items(), 
                                key=lambda x: len(x[1]), 
                                reverse=True):
            if len(files) > 1:
                duplicates[name] = files[:10]  # 每个文件名只保留最多10个文件
                count += 1
                if count >= 50:  # 最多返回50个重复文件名
                    break
        
        return duplicates